﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;

class ExplorerUtil
{
    #region Win32_API
    /// <summary>  
    /// 定义调用的API方法  
    /// </summary>  
    class Win32
    {
        [DllImport("shell32.dll")]
        public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);

    }
    #endregion

    #region 读取应用程序图标

    /// <summary>
    /// 依据文件名读取图标，若指定文件不存在，则返回空值。  
    /// </summary>
    /// <param name="fileName">文件路径</param>
    /// <param name="isLarge">是否返回大图标</param>
    /// <returns></returns>
    public static Icon GetIconByFileName(string fileName, bool isLarge = true)
    {
        int[] phiconLarge = new int[1];
        int[] phiconSmall = new int[1];
        //文件名 图标索引 
        Win32.ExtractIconEx(fileName, 0, phiconLarge, phiconSmall, 1);
        IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);
        return Icon.FromHandle(IconHnd);
    }

    /// <summary>  
    /// 根据文件扩展名（如:.*），返回与之关联的图标。
    /// 若不以"."开头则返回文件夹的图标。  
    /// </summary>  
    /// <param name="fileType">文件扩展名</param>  
    /// <param name="isLarge">是否返回大图标</param>  
    /// <returns></returns>  
    public static Icon GetIconByFileType(string fileType, bool isLarge)
    {
        if (fileType == null || fileType.Equals(string.Empty)) return null;

        RegistryKey regVersion = null;
        string regFileType = null;
        string regIconString = null;
        string systemDirectory = Environment.SystemDirectory + "\\";

        if (fileType[0] == '.')
        {
            //读系统注册表中文件类型信息  
            regVersion = Registry.ClassesRoot.OpenSubKey(fileType, true);
            if (regVersion != null)
            {
                regFileType = regVersion.GetValue("") as string;
                regVersion.Close();
                regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"\DefaultIcon", true);
                if (regVersion != null)
                {
                    regIconString = regVersion.GetValue("") as string;
                    regVersion.Close();
                }
            }
            if (regIconString == null)
            {
                //没有读取到文件类型注册信息，指定为未知文件类型的图标  
                regIconString = systemDirectory + "shell32.dll,0";
            }
        }
        else
        {
            //直接指定为文件夹图标  
            regIconString = systemDirectory + "shell32.dll,3";
        }
        string[] fileIcon = regIconString.Split(new char[] { ',' });
        if (fileIcon.Length != 2)
        {
            //系统注册表中注册的标图不能直接提取，则返回可执行文件的通用图标  
            fileIcon = new string[] { systemDirectory + "shell32.dll", "2" };
        }
        Icon resultIcon = null;
        try
        {
            //调用API方法读取图标  
            int[] phiconLarge = new int[1];
            int[] phiconSmall = new int[1];
            uint count = Win32.ExtractIconEx(fileIcon[0], Int32.Parse(fileIcon[1]), phiconLarge, phiconSmall, 1);
            IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);
            resultIcon = Icon.FromHandle(IconHnd);
        }
        catch { }
        return resultIcon;
    }

    #endregion

    #region exe,dll工具方法

    /// <summary>
    /// 判断程序或dll是x86还是x64(可能返回的两种结果：0x10b - PE32 0x20b - PE32+)
    /// </summary>
    /// <param name="pFilePath"></param>
    /// <returns></returns>
    public static ushort GetPEArchitecture(string pFilePath)
    {
        ushort architecture = 0;
        try
        {
            using (System.IO.FileStream fStream = new System.IO.FileStream(pFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                using (System.IO.BinaryReader bReader = new System.IO.BinaryReader(fStream))
                {
                    if (bReader.ReadUInt16() == 23117) //check the MZ signature
                    {
                        fStream.Seek(0x3A, System.IO.SeekOrigin.Current); //seek to e_lfanew.
                        fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin); //seek to the start of the NT header.
                        if (bReader.ReadUInt32() == 17744) //check the PE\0\0 signature.
                        {
                            fStream.Seek(20, System.IO.SeekOrigin.Current); //seek past the file header,
                            architecture = bReader.ReadUInt16(); //read the magic number of the optional header.
                        }
                    }
                }
            }
        }
        catch (Exception) { /* TODO: Any exception handling you want to do, personally I just take 0 as a sign of failure */}
        //if architecture returns 0, there has been an error.
        return architecture;
    }
    #endregion

    #region 快捷方式

    ////需要引入IWshRuntimeLibrary，搜索Windows Script Host Object Model

    ///// <summary>
    ///// 创建快捷方式
    ///// </summary>
    ///// <param name="directory">快捷方式所处的文件夹</param>
    ///// <param name="shortcutName">快捷方式名称</param>
    ///// <param name="targetPath">目标路径</param>
    ///// <param name="description">描述</param>
    ///// <param name="iconLocation">图标路径，格式为"可执行文件或DLL路径, 图标编号"，
    ///// 例如System.Environment.SystemDirectory + "\\" + "shell32.dll, 165"</param>
    ///// <remarks></remarks>
    //public static void CreateShortcut(string directory, string shortcutName, string targetPath,
    //    string description = null, string iconLocation = null)
    //{
    //    if (!System.IO.Directory.Exists(directory))
    //    {
    //        System.IO.Directory.CreateDirectory(directory);
    //    }

    //    string shortcutPath = Path.Combine(directory, string.Format("{0}.lnk", shortcutName));
    //    WshShell shell = new WshShell();
    //    IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);//创建快捷方式对象
    //    shortcut.TargetPath = targetPath;//指定目标路径
    //    shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath);//设置起始位置
    //    shortcut.WindowStyle = 1;//设置运行方式，默认为常规窗口
    //    shortcut.Description = description;//设置备注
    //    shortcut.IconLocation = string.IsNullOrEmpty(iconLocation) ? targetPath : iconLocation;//设置图标路径
    //    shortcut.Save();//保存快捷方式
    //}

    ///// <summary>
    ///// 创建桌面快捷方式
    ///// </summary>
    ///// <param name="shortcutName">快捷方式名称</param>
    ///// <param name="targetPath">目标路径</param>
    ///// <param name="description">描述</param>
    ///// <param name="iconLocation">图标路径，格式为"可执行文件或DLL路径, 图标编号"</param>
    ///// <remarks></remarks>
    //public static void CreateShortcutOnDesktop(string shortcutName, string targetPath,
    //    string description = null, string iconLocation = null)
    //{
    //    string desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);//获取桌面文件夹路径
    //    CreateShortcut(desktop, shortcutName, targetPath, description, iconLocation);
    //}

    #endregion

    #region 进程
    /// <summary>
    /// 指定进程是否存在
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static bool IsTheProcessOnRunning(string name)
    {
        try
        {
            return Process.GetProcessesByName(name).ToList().Count > 0;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 指定进程是否存在
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static bool IsTheProcessOnRunning(int id)
    {
        try
        {
            return Process.GetProcessById(id) == null;
        }
        catch
        {
            return false;
        }
    }
    #endregion

}
